#!/usr/bin/python

import os,string,cgi,time,re, sys,random,inspect,daemon,logging
import pid 
from threadingTimers import threadingTimer
from yapsy.PluginManager import PluginManager
from pluginsCategories import pySKFWDaemons,pySKFWServices
from pySKFW import *
#from tornado.options import define, options

logging.basicConfig(level=logging.DEBUG)
gbl_temp_path = '/tmp/ram/'
daemonMode = True

class pyServer(pySKFW):
    ki = None
    capture = -1
    kondoMotions={}
    tick = 0
    thread = None
    servers = {}
    services = {}
    provided = {}
    timers = {}
    tmp_path = gbl_temp_path
    categories_filter = {
        "Daemons"   : pySKFWDaemons,
        "Services"  : pySKFWServices
    }
    def getService(self,serviceName,list=False):
        if (list):
            logging.warning("!!!!!!!!!!!!getService todo for list")
            return None
        else:
            try:
                return self.provided[serviceName][0]
            except IndexError :
                logging.error("No provider for %s at Index 0 " % serviceName)
                return None
            except KeyError :
                logging.error("No provider for %s" % serviceName)
                return None
    def start(self):
        # Create the plugin manager
        self.manager = PluginManager(self.categories_filter)
        self.manager.setPluginPlaces(["plugins"])
        # Load plugins
        self.manager.locatePlugins()
        self.manager.loadPlugins()
        logging.info("initializing Daemons....")
        for plugin in self.manager.getPluginsOfCategory("Daemons"):
            logging.info (" - " + plugin.plugin_object.name)
            self.servers[plugin.plugin_object.name] = plugin.plugin_object
            self.servers[plugin.plugin_object.name].tmpPath = self.tmp_path
            self.servers[plugin.plugin_object.name].init(self)
            
        logging.info("Starting Services....")
        for plugin in  self.manager.getPluginsOfCategory("Services"):
            logging.info (" - " + plugin.plugin_object.name)
            self.services[plugin.plugin_object.name] = plugin.plugin_object
            self.services[plugin.plugin_object.name].tmpPath = self.tmp_path
            self.services[plugin.plugin_object.name].init(self)
            logging.info (" - ok " + plugin.plugin_object.name)
            
            for service in self.services[plugin.plugin_object.name].provides:
                obj= self.services[plugin.plugin_object.name].provides[service]
                logging.info("  - adding [%s] to provided by [%s]"%(service,plugin.plugin_object.name))
                if (service not in self.provided):
                    self.provided[service] = []
                self.provided[service].append(service)
                for srv in self.servers:
                    self.servers[srv].addReturnHandler(obj['resultType'],obj['path'],obj['handler'])
                
        logging.info("Init ok....")

        logging.info("Starting daemons")
        for plugin in self.servers:
            logging.info ("  - start : %s " % plugin)
            self.servers[plugin].start(self)
            
    def stop(self):
        logging.info ("Stopping Timers")
        for plugin in self.timers:
            try:
                self.timers[plugin].stop()
                logging.info ("  - stop %s" % plugin)
            finally : 
                logging.info ("  - stopped : %s" % plugin)

        logging.info ("Stopping servers")
        for plugin in self.servers:
            try:
                self.servers[plugin].stop()
                logging.info ("  - stop %s" % plugin)
            finally : 
                logging.info ("  - stopped : %s" % plugin)

        logging.info ("Stopping services")
        for plugin in self.services:
            try:
                self.services[plugin].stop()
                logging.info ("  - stop : %s" % plugin)
            finally : 
                logging.info ("  - stopped : %s" % plugin)
        
        logging.info('Servers/Services/Timers stopped')
        
    def initTimer(self,serviceName,timerName,delay,callback,params=[]):
        logging.info('Init timer : %s/%s (%s)' % (serviceName,timerName,delay))
        self.timers[serviceName+'__'+timerName] = threadingTimer(delay, callback, params)
        self.timers[serviceName+'__'+timerName].start()

    def stopTimer(self,serviceName,timerName):
        logging.info('Stopping timer : %s/%s (%s)' % (serviceName,timerName,delay))
        self.timers[serviceName+'__'+timerName].stop()

    def addServersHandlers(self,resultType,path,handler):
        logging.info ("Add handlers %s:%s"%(path,handler))
        for plugin in self.servers:
            self.servers[plugin].addReturnHandler(resultType,path,handler)
            logging.info ("  - handler OK")

       
#define("port", default=8888, help="run on the given port", type=int)

def mainStop():
    global pidfile_path, psrv

    print "\n" 
    logging.info("Stop signal received, shutting down .....")
    psrv.stop()
    # ensure we remove the pidfile
    pid.remove(pidfile_path)
    print "\n"

def main():
    global pidfile_path, psrv,daemonMode
    
    # check pidfile
    
    # daemonize
    if daemonMode:
        pidfile_path = gbl_temp_path + 'pyKondoServer'
        pid.check(pidfile_path)
        logging.info("pid %s" %(pidfile_path))
        daemon_context = daemon.DaemonContext(stdout=sys.stdout, stderr=sys.stderr, working_directory='.')
        with daemon_context:
            # write the pidfile
            pid.write(pidfile_path)
            # enter the Tornado IO loop'''
    sys.exitfunc = mainStop 
    psrv = pyServer()
    psrv.start();

if __name__ == '__main__':
    main()    
    
